#include "dashun.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void ObjMap_init(struct ObjMap *M, wchar_t *msg) {
    M->msg = msg;
    M->n_size = 0;
    M->p_size = 0;
    M->next = NULL;
    M->prev = NULL;
}

struct ObjMap *crtNod(wchar_t *msg) {
    struct ObjMap *M = (struct ObjMap *)malloc(sizeof(struct ObjMap));
    if (!M) {
        perror("MALLOC");
        exit(1);
    }
    ObjMap_init(M, msg);
    return M;
} // 创建节点并且初始化

static void adNxt(struct ObjMap *M0, struct ObjMap *M1) {
    int size = M0->n_size + 1;
    struct ObjMap **new = (struct ObjMap **)realloc((void *)M0->next, size * sizeof(struct ObjMap *));
    if (!new) {
        perror("REALLOC");
        exit(2);
    }
    new[size-1] = M1;
    M0->next =  new;
    M0->n_size = size;
} // 添加后继


static void adPrv(struct ObjMap *M0, struct ObjMap *M1) {
    int size = M0->n_size + 1;
    struct ObjMap **new = (struct ObjMap **)realloc((void *)M0->prev, size * sizeof(struct ObjMap *));
    if (!new) {
        perror("REALLOC");
        exit(2);
    }
    new[size-1] = M1;
    M0->prev =  new;
    M0->p_size = size;
}

static struct ObjMap *adLnk(struct ObjMap *M, struct ObjMap *S) {
    adNxt(M, S);
    adPrv(S, M);
    return S;
} // 新建一对连接

struct ObjMap *crtLnk(struct ObjMap *M, struct ObjMap *S) {
    if (!S) S = crtNod();
    return adLnk(M, S);
} // 创建一个连接，如果S为空则先新建一个节点


void initList(struct ObjList *L) {
    L->size = 0;
    L->list = NULL;
} //初始化对象表

static void adLst(struct ObjList *L, struct ObjMap *M) {
    size_t top = L->size + 1;
    struct ObjMap **new = (struct ObjMap **)realloc(L->list, top * sizeof(struct ObjMap *));
    new[top-1] = M;
    L->list = new;
    L->size = top;
}

static int inList(struct ObjList *L, struct ObjMap *M) {
    struct ObjMap **P = L->list;
    for (int i=0;i < L->size; ++i) {
        if (P[i] == M) return 1;
    }
    return 0;
}


void travObj(struct ObjList *L,  struct ObjMap * M) {
    if (!inList(L, M)) adLst(L, M);
    for (int i=0; i<M->n_size; ++i) {
        travObj(L, M->next[i]);
    }
}// 遍历对象图

void lsFree(struct ObjList *L) {
    for (int i=0; i < L->size; ++i) {
        free(L->list[i]);
    }
}